/**
 * =====================================================================================
 *
 *      @file:  expression.h
 *
 *    	@brief:  表达式计算，一个树和一簇回调函数
 *
 *      @version:  1.0
 *      Created:  2010年04月13日 11时45分12秒
 *      Revision:  none
 *      Compiler:  gcc -Wall -Wextra expression.h
 *
 *      @author:  easyeagel (LiuGuangBao), easyeagel@gmx.com
 *      Company:  简单C++ - www.easycpp.org
 *
 * =====================================================================================
 */

#ifndef M_magus_db_expression_h
#define M_magus_db_expression_h
#ifdef __cplusplus
#include<cstring>
extern "C"
{
#else
#include<string.h>
#endif

#define RLT_int_op 0
#define RLT_double_op 1
#define RLT_string_op 2
#define RLT_add_op 3
#define RLT_sub_op 4
#define RLT_multi_op 5
#define RLT_div_op 6
#define RLT_and_op 7
#define RLT_or_op  8
#define RLT_not_op 9
#define RLT_equal_op 10
#define RLT_not_equal_op 11
#define RLT_field_op 12

/**
 * @brief 在表达式值的类型上指定表达式处理方式
 * @see RLTexpression_t
 */
typedef enum value_t
{
	value_none=0,

	value_int=1,
	value_double,
	value_string,
	value_bool,
} value_t;

/**
 * @brief 一个表达式结点结构
 */
typedef struct RLTexpression_t
{
	size_t index; /**< 运算符序号 */
	union
	{
		struct RLTexpression_t* single; /**< 对于一元运算符 */
		struct
		{
			struct RLTexpression_t* left;
			struct RLTexpression_t* right;
		}binary; /**< 对于二元运算符 */
		struct
		{
			struct RLTexpression_t* first;
			struct RLTexpression_t* second;
			struct RLTexpression_t* third;
		}ternary; /**< 对于三元运算符 */
	}param;
	struct
	{
		value_t type; /**< 表达式类型 */
		union
		{
			double dvalue;
			int ivalue;
			const char* svalue;
		}value; /**< 表达式树的叶子 */
	}result;
}RLTexpression_t;

typedef void (*operator_call_t)(RLTexpression_t* exp, void* data);
typedef void (*operator_reset_t)(RLTexpression_t* exp, void* data);
typedef void (*operator_free_t)(RLTexpression_t* exp, void* data);

/**
 * @brief 运算符类型的定义
 * @see operator_t
 */
typedef enum operator_type_t
{
	value_none_opt, /**< 不是运算 */
	value_val_opt, /**< 值运算 */
	value_filed_opt, /**< 字段运算 */
	value_fun_opt, /**< 函数调用 */
	value_one_opt, /**< 一元运算 */
	value_two_opt,
	value_three_opt,
}operator_type_t;

/**
* @brief 存在一个命令字典，本结构是这个字典的元素结构
*/
typedef struct operator_t
{
	operator_type_t type; /**< 运算类型的信息 */
	operator_call_t call;
	operator_reset_t reset;
	operator_free_t clear;
	void* data;
}operator_t;

/**
 * @brief 全局的命令字典模板，创建一个新字典时需要使用这个字典作为模板
 */
extern operator_t g_operator_dict[];

/**
* @brief 新建一个表达式结点，用户应该始终使用本函数来新结点
*
* @param optype 这个结点运算符编号或类型
*
* @return 返回指向新结点的地址
*/
RLTexpression_t* rlt_exp_create(size_t optype);

/**
* @brief 销毁一个结点，用户应该始终调用这个函数来销毁一个结点
*
* @param exp 需要销毁的结点地址
*/
void rlt_exp_free(RLTexpression_t* exp, operator_t* dict);

/**
* @brief 执行一个表达式
*
* @param exp 表达式根结点
* @param dict 执行字典，将从这个字典里查找合适的回调函数
*/
void rlt_exp_execute(RLTexpression_t* exp, operator_t* dict);

/**
* @brief 如果一个运算符是一元的，那么使用此函数设置其操作因子
*
* @param exp 运算符指向的结点
* @param single 操作因子
*/
void rlt_exp_single(RLTexpression_t* exp, RLTexpression_t* single);

/**
* @brief 如果一个运算符是二元的，那么使用此函数设置其左操作因子
*
* @param exp 运算符指向的结点
* @param left 操作因子
*/
void rlt_exp_left(RLTexpression_t* exp, RLTexpression_t* left);

/**
* @brief 如果一个运算符是二元的，那么使用此函数设置其右操作因子
*
* @param exp 运算符指向的结点
* @param right 操作因子
*/
void rlt_exp_right(RLTexpression_t* exp, RLTexpression_t* right);

/**
* @brief 如果一个运算符是三元的，那么使用此函数设置其第一个操作因子
*
* @param exp 运算符指向的结点
* @param first 操作因子
*/
void rlt_exp_first(RLTexpression_t* exp, RLTexpression_t* first);

/**
* @brief 如果一个运算符是三元的，那么使用此函数设置其第二个操作因子
*
* @param exp 运算符指向的结点
* @param first 操作因子
*/
void rlt_exp_second(RLTexpression_t* exp, RLTexpression_t* second);

/**
* @brief 如果一个运算符是三元的，那么使用此函数设置其第三个操作因子
*
* @param exp 运算符指向的结点
* @param first 操作因子
*/
void rlt_exp_third(RLTexpression_t* exp, RLTexpression_t* third);

/**
* @brief 把结点设置为值结点，同时把值类型设置为double型，并设置其值
*
* @param exp 指定的结点
* @param value 指定的值
*/
void rlt_exp_dvalue(RLTexpression_t* exp, double value);

/**
* @brief 把结点设置为值结点，同时把值类型设置为int型，并设置其值
*
* @param exp 指定的结点
* @param value 指定的值
*/
void rlt_exp_ivalue(RLTexpression_t* exp, int value);

/**
* @brief 把结点设置为值结点，同时把值类型设置为字符串型，并设置其值
*
* @param exp 指定的结点
* @param value 指定的值
*/
void rlt_exp_svalue(RLTexpression_t* exp, const char* value);

#ifndef M_expression_implement
#define rlt_exp_single(exp, v) ((void)((exp)->param.single=(v)))
#define rlt_exp_left(exp, v) ((void)((exp)->param.binary.left=(v)))
#define rlt_exp_right(exp, v) ((void)((exp)->param.binary.right=(v)))
#define rlt_exp_first(exp, v) ((void)((exp)->param.ternary.first=(v)))
#define rlt_exp_second(exp, v) ((void)((exp)->param.ternary.second=(v)))
#define rlt_exp_third(exp, v) ((void)((exp)->param.ternary.third=(v)))
#define rlt_exp_dvalue(exp, v) ((void)((exp)->result.type=value_double, (exp)->result.value.dvalue=(v)))
#define rlt_exp_ivalue(exp, v) ((void)((exp)->result.type=value_int, (exp)->result.value.ivalue=(v)))
#define rlt_exp_svalue(exp, v) ((void)((exp)->result.type=value_string, (exp)->result.value.svalue=(v)))
#endif /* M_expression_implement */

#define EXP_single(exp) ((exp)->param.single)
#define EXP_left(exp) ((exp)->param.binary.left)
#define EXP_right(exp) ((exp)->param.binary.right)
#define EXP_first(exp) ((exp)->param.ternary.first)
#define EXP_second(exp) ((exp)->param.ternary.second)
#define EXP_third(exp) ((exp)->param.ternary.third)
#define EXP_type(exp) ((exp)->result.type)
#define EXP_dvalue(exp) ((exp)->result.value.dvalue)
#define EXP_ivalue(exp) ((exp)->result.value.ivalue)
#define EXP_svalue(exp) ((exp)->result.value.svalue)

#ifdef __cplusplus
}
#endif

#endif /* M_magus_db_expression_h */

